//
// Created by casdon on 2024/8/19.
//

#ifndef CIOT_CSDK_CIOT_CLOUD_H
#define CIOT_CSDK_CIOT_CLOUD_H

#include "types.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef enum Ciot_cloud_topic_e
{
    Ciot_cloud_topic_timeSync,
    Ciot_cloud_topic_access,
    Ciot_cloud_topic_binding,

    Ciot_cloud_topic_status,
    Ciot_cloud_topic_notify,

    Ciot_cloud_topic_action,
    Ciot_cloud_topic_queue,

    Ciot_cloud_topic_request,
    Ciot_cloud_topic_response,

    Ciot_cloud_topic_MAX

} Ciot_cloud_topic;

typedef enum Ciot_cloud_connection_status_e {
    Ciot_cloud_connection_status_idle = 0,
    Ciot_cloud_connection_status_ready,
    Ciot_cloud_connection_status_start_failed,
    Ciot_cloud_connection_status_connecting,
    Ciot_cloud_connection_status_connected,
    Ciot_cloud_connection_status_timeout,
    Ciot_cloud_connection_status_auth_failed,
    Ciot_cloud_connection_status_no_access,
    Ciot_cloud_connection_status_binding_failed,
    Ciot_cloud_connection_status_binding_ok,
    Ciot_cloud_connection_status_connecting_channel,
    Ciot_cloud_connection_status_succeed,

    Ciot_cloud_connection_status_MAX
} Ciot_cloud_connection_status;

typedef struct ciot_product_data_t {
    uint8_t id;
    union {
        bool bool_v;
        int64_t int_v;
        double double_v;
        uint8_t enum_v;
        uint64_t bits_v;
        char *string_v;
        uint8_t *raw_v;
    };
    Ciot_product_data_type type;

    /**
     * Must specific when use  string, raw types
     */
    uint16_t len;

} ciot_product_data;

typedef     Ciot_res    (* CommandReceivedHandler)         ( const char * event, ciot_product_data ** args );
typedef     void        (* CloudStatusChangedHandler)      ( Ciot_cloud_connection_status status );
typedef     Ciot_res    (* CommandRawReceivedHandler)      ( int eventId, const char * event, const cJSON * args );
typedef     Ciot_res    (* APIReceivedHandler)             ( const char * api, const cJSON * content, Ciot_res status, const char * message );

typedef struct ciot_cloud_manager_t
{
    Ciot_res    (* report_status_data)        ( ciot_product_data * status );
    Ciot_res    (* report_status_data_force)  ( ciot_product_data * status );

    Ciot_res    (* report_status)             ( ciot_product_data status );
    Ciot_res    (* report_status_force)       ( ciot_product_data status );

    Ciot_res    (* report_notify)             ( uint16_t eventID, const char * event );
    Ciot_res    (* report_notify_message)     ( uint16_t eventID, const char * event, const char * string_message);

    /**
     * @deprecated
     */
    Ciot_res    (* command_received)          ( const char * event, ciot_product_data ** args );

    Ciot_res    (* command_raw_received)       ( int eventId, const char * event, const cJSON * args );

    Ciot_res    (* dp_command_received)       ( const ciot_product_data ** data, uint16_t dp_count );

    Ciot_res    (* system_command_received)   ( int eventId, const char * event, const cJSON * args );

    void        (* cloud_status_changed)      ( Ciot_cloud_connection_status status );

    /**
     * APIs
     *
     */

    /**
     * Request API by Ciot cloud
     * param api, payload need to be release when done
     * @param api (used in event name)
     * @param payload
     * @return
     */
    Ciot_res    (* api_request)               ( const char * api, const cJSON * payload );

    /**
     * API Response by Ciot cloud
     * @param api
     * @param content
     * @param status
     * @param message
     * @return
     */
    Ciot_res    (* api_response)              ( const char * api, const cJSON * content, Ciot_res status, const char * message );

} ciot_cloud_manager;

CIOT_PRIVATE
const ciot_cloud_manager * ciot_cloud_manager_init();

CIOT_API
const ciot_cloud_manager * ciot_cloud_manager_instance();

CIOT_API
Ciot_res ciot_cloud_set_command_received_handler( CommandReceivedHandler handler );

CIOT_API
Ciot_res ciot_cloud_set_command_raw_received_handler( CommandRawReceivedHandler handler );

CIOT_API
Ciot_res ciot_cloud_set_cloud_status_changed_handler( CloudStatusChangedHandler handler );

CIOT_API
Ciot_res ciot_cloud_set_api_response_handler( APIReceivedHandler handler );

#define ciot_cloud_mgr()    ciot_cloud_manager_instance()
#define ciot_cloud()        ciot_cloud_mgr()

const char * ciot_cloud_get_validate_sign( Ciot_time_ms timestamp, const char * nonce );
// need to free the return value

bool ciot_cloud_check_validate_sign( const char * pid, const char * did, Ciot_time_ms timestamp, const char * nonce, const char * sign );

#ifdef __cplusplus
}
#endif

#endif //CIOT_CSDK_CIOT_CLOUD_H
